import 'dart:async';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
import 'package:get/get.dart';
import 'package:openim_common/openim_common.dart';
import 'package:openim_common/src/models/post.dart';

class Apis {
  static Options get imTokenOptions => Options(headers: {'token': DataSp.imToken});

  static Options get chatTokenOptions => Options(headers: {'token': DataSp.chatToken});

  static Options get domainJwtOptions => Options(headers: {'Authorization': 'Bearer ${DataSp.getLoginCertificate()?.token}'});

  static StreamController kickoffController = StreamController<int>.broadcast();

  static void _kickoff(int? errCode) {
    if (errCode == 1501 || errCode == 1503 || errCode == 1504 || errCode == 1505) {
      kickoffController.sink.add(errCode);
    }
  }
  /// 通过验证码登录
  static Future<LoginCertificate> loginWithVerificationCode({
    String? areaCode,
    String? phoneNumber,
    required String verificationCode,
  }) async {
    try {
      var data = await HttpUtil.post(Urls.loginWithCode, data: {
        "phone": phoneNumber,
        "area_code": areaCode,
        "verification_code": verificationCode,
        "platform": IMUtils.getPlatform(),
      });
      
      // 根据domain-backend的响应格式解析数据
      debugPrint(data.toString());
      // 正确解析AuthResponse格式
      if (data != null) {
        final cert = LoginCertificate.fromJson({
          'openimUserID': data['user']['openim_user_id'],
          'userID': data['user']['user_id'],
          'token': data['token'],
          'imToken': data['im_token'],
          'chatToken': data['chat_token'],
        });
        return cert;
      } else {
        throw Exception('登录响应数据为空');
      }
    } catch (e, s) {
      _catchErrorHelper(e, s);
      return Future.error(e);
    }
  }

  static Future<LoginCertificate> login({
    String? areaCode,
    String? phoneNumber,
    String? account,
    String? email,
    String? password,
    String? verificationCode,
  }) async {
    try {
      // 使用domain-backend的登录接口和参数格式
      var data = await HttpUtil.post(Urls.login, data: {
        "email": email,
        "phone": phoneNumber ?? account, // 使用phone字段
        "password": password != null ? IMUtils.generateMD5(password) : null,
        "area_code": areaCode, // 使用area_code字段名
        "login_openim": true, // 默认登录OpenIM
        "platform": IMUtils.getPlatform(),
      });
        // 根据domain-backend的AuthResponse格式解析数据
      if (data != null) {
        final cert = LoginCertificate.fromJson({
          'openimUserID': data['user']['openim_user_id'],
          'userID': data['user']['user_id'],
          'token': data['token'],
          'imToken': data['im_token'],
          'chatToken': data['chat_token'],
        });
      return cert;
      }else{
        throw Exception('登录响应数据为空');
      }
    } catch (e, s) {
      _catchErrorHelper(e, s);

      return Future.error(e);
    }
  }

  // static Future<LoginCertificate> register({
  //   required String nickname,
  //   required String password,
  //   String? faceURL,
  //   String? areaCode,
  //   String? phoneNumber,
  //   String? email,
  //   String? account,
  //   int birth = 0,
  //   int gender = 1,
  //   required String verificationCode,
  //   String? invitationCode,
  // }) async {
  //   try {
  //     var data = await HttpUtil.post(Urls.register, data: {
  //       'phone': phoneNumber,
  //       'password': IMUtils.generateMD5(password),
  //       'username': account ?? phoneNumber, // 使用account或phoneNumber作为username
  //       'nickname': nickname,
  //       'email': email,
  //       'area_code': areaCode,
  //       'country': '', // 可以根据需要添加
  //       'city': '', // 可以根据需要添加
  //       // 'deviceID': DataSp.getDeviceID(),
  //       // 'verifyCode': verificationCode,
  //       // 'platform': IMUtils.getPlatform(),
  //       // 'invitationCode': invitationCode,
  //       // 'autoLogin': true,
  //       // 'user': {
  //       //   "nickname": nickname,
  //       //   "faceURL": faceURL,
  //       //   'birth': birth,
  //       //   'gender': gender,
  //       //   'email': email,
  //       //   "areaCode": areaCode,
  //       //   'phoneNumber': phoneNumber,
  //       //   'account': account,
  //       //   'password': IMUtils.generateMD5(password),
  //       // },
  //     });

  //     final cert = LoginCertificate.fromJson(data!);

  //     return cert;
  //   } catch (e, s) {
  //     _catchErrorHelper(e, s);

  //     return Future.error(e);
  //   }
  // }

  static Future<LoginCertificate> register({
  required String nickname,
  required String password,
  String? faceURL,
  String? areaCode,
  String? phoneNumber,
  String? email,
  String? account,
  int birth = 0,
  int gender = 1,
  required String verificationCode,
  String? invitationCode,
}) async {
  try {

    // 选择接口：如果有 email 且没有手机号，走邮箱注册接口
    final isEmailMode = (email != null && (phoneNumber == null || phoneNumber.isEmpty));
    final url = isEmailMode ? Urls.registerEmail : Urls.register;
    final requestBody = isEmailMode
        ? {
            'email': email,
            'password': IMUtils.generateMD5(password),
            'username': account ?? (email ?? nickname),
            'nickname': nickname,
            'country': '',
            'city': '',
            'platform': IMUtils.getPlatform(),
          }
        : {
            'phone': phoneNumber,
            'password': IMUtils.generateMD5(password),
            'username': account ?? phoneNumber,
            'nickname': nickname,
            'email': email,
            'area_code': areaCode,
            'country': '',
            'city': '',
            'platform': IMUtils.getPlatform(),
          };
    // 使用domain-backend期望的请求格式
    var response = await HttpUtil.post(url, data: requestBody);
     // 正确解析嵌套的响应结构
    final user = response['user'];
    final cert = LoginCertificate.fromJson({
        'userID': user['openim_user_id'],
        'token': user['token'],
        'imToken': user['im_token'],
        'chatToken': user['chat_token'],
      });
    return cert;
  } catch (e, s) {
    _catchErrorHelper(e, s);
    return Future.error(e);
  }
}

  // static Future<dynamic> resetPassword({
  //   String? areaCode,
  //   String? phoneNumber,
  //   String? email,
  //   required String password,
  //   required String verificationCode,
  // }) async {
  //   try {
  //     return HttpUtil.post(
  //       Urls.resetPwd,
  //       data: {
  //         "areaCode": areaCode,
  //         'phoneNumber': phoneNumber,
  //         'email': email,
  //         'password': IMUtils.generateMD5(password),
  //         'verifyCode': verificationCode,
  //         'platform': IMUtils.getPlatform(),
  //       },
  //       options: chatTokenOptions,
  //     );
  //   } catch (e, s) {
  //     _catchErrorHelper(e, s);
  //   }
  // }
  static Future<dynamic> resetPassword({
    String? areaCode,
    String? phoneNumber,
    String? email,
    required String password,
    required String verificationCode,
  }) async {
    try {
      Map<String, dynamic> data = {
        "verification_code": verificationCode,
        "new_password": IMUtils.generateMD5(password),
      };

      // 根据输入类型添加相应字段
      if (email != null && email.isNotEmpty) {
        data["email"] = email;
      } else if (phoneNumber != null && phoneNumber.isNotEmpty) {
        data["phone"] = phoneNumber;
        data["area_code"] = areaCode ?? "+86";
      }

      return HttpUtil.post(
        Urls.resetPwd,
        data: data,
      );
    } catch (e, s) {
      _catchErrorHelper(e, s);
    }
  }
  static Future<bool> changePassword({
    required String userID,
    required String currentPassword,
    required String newPassword,
  }) async {
    try {
      await HttpUtil.post(
        Urls.changePwd,
        data: {
          "userID": userID,
          'currentPassword': IMUtils.generateMD5(currentPassword),
          'newPassword': IMUtils.generateMD5(newPassword),
          'platform': IMUtils.getPlatform(),
        },
        options: domainJwtOptions,
      );
      return true;
    } catch (e, s) {
      _catchErrorHelper(e, s);

      return false;
    }
  }

  static Future<bool> changePasswordOfB({
    required String newPassword,
  }) async {
    try {
      await HttpUtil.post(
        Urls.resetPwd,
        data: {
          'password': IMUtils.generateMD5(newPassword),
          'platform': IMUtils.getPlatform(),
        },
        options: chatTokenOptions,
      );
      return true;
    } catch (e) {
      return false;
    }
  }

  static Future<dynamic> updateUserInfo({
    required String userID,
    String? phoneNumber,
    String? areaCode,
    String? email,
    String? nickname,
    String? faceURL,
    int? gender,
    int? birth,
    String? ex,
    String? country,
    String? city,
  }) async {
    try {
      final Map<String, dynamic> body = {};
      void put(String key, dynamic value) {
        if (value != null) body[key] = value;
      }
      put('nickname', nickname);
      put('avatar', faceURL);
      put('bio', ex);
      put('gender', gender);
      put('birth', birth);
      put('email', email);
      if (phoneNumber != null) put('phone', phoneNumber);
      if (areaCode != null) put('area_code', areaCode);
      put('country', country);
      put('city', city);

      return HttpUtil.put(
        Urls.updateUserInfo,
        data: body,
        options: domainJwtOptions,
      );
    } catch (e, s) {
      _catchErrorHelper(e, s);
    }
  }
  static Future<List<FriendInfo>> searchFriendInfo(
    String keyword, {
    int pageNumber = 1,
    int showNumber = 10,
    bool showErrorToast = true,
  }) async {
    try {
      final data = await HttpUtil.post(
        Urls.searchFriendInfo,
        data: {
          'pagination': {'pageNumber': pageNumber, 'showNumber': showNumber},
          'keyword': keyword,
        },
        options: chatTokenOptions,
        showErrorToast: showErrorToast,
      );
      if (data['users'] is List) {
        return (data['users'] as List).map((e) => FriendInfo.fromJson(e)).toList();
      }
      return [];
    } catch (e, s) {
      _catchErrorHelper(e, s);

      rethrow;
    }
  }

  static Future<List<UserFullInfo>?> getUserFullInfo({
    int pageNumber = 0,
    int showNumber = 10,
    required List<String> userIDList,
  }) async {
    try {
      final data = await HttpUtil.post(
        Urls.getUsersFullInfo,
        data: {
          'pagination': {'pageNumber': pageNumber, 'showNumber': showNumber},
          'userIDs': userIDList,
          'platform': IMUtils.getPlatform(),
        },
        options: chatTokenOptions,
      );
      if (data['users'] is List) {
        return (data['users'] as List).map((e) => UserFullInfo.fromJson(e)).toList();
      }
      return null;
    } catch (e, s) {
      _catchErrorHelper(e, s);

      return [];
    }
  }

  static Future<UserFullInfo?> getOpenIMUserProfile(String userID) async {
    try {
      final list = await getUserFullInfo(userIDList: [userID], pageNumber: 1, showNumber: 1);
      if (list != null && list.isNotEmpty) {
        return list.first;
      }
      return null;
    } catch (e, s) {
      _catchErrorHelper(e, s);
      return null;
    }
  }

  static Future<List<UserFullInfo>?> searchUserFullInfo({
    required String content,
    int pageNumber = 1,
    int showNumber = 10,
  }) async {
    try {
      final data = await HttpUtil.post(
        Urls.searchUserFullInfo,
        data: {
          'pagination': {'pageNumber': pageNumber, 'showNumber': showNumber},
          'keyword': content,
        },
        options: chatTokenOptions,
      );
      if (data['users'] is List) {
        return (data['users'] as List).map((e) => UserFullInfo.fromJson(e)).toList();
      }
      return null;
    } catch (e, s) {
      _catchErrorHelper(e, s);

      return [];
    }
  }

  static Future<String?> getUserIDByContact({
    String? phone,
    String? areaCode,
    String? email,
  }) async {
    try {
      final data = await HttpUtil.get(
        Urls.getUserIDByContact,
        queryParameters: {
          if (phone != null && phone.isNotEmpty) 'phone': phone,
          if (areaCode != null && areaCode.isNotEmpty) 'area_code': areaCode,
          if (email != null && email.isNotEmpty) 'email': email,
        },
        options: chatTokenOptions,
      );
      if (data is Map && data['user_id'] is String) {
        return data['user_id'] as String;
      }
      return null;
    } catch (e, s) {
      _catchErrorHelper(e, s);
      return null;
    }
  }

  static Future<UserFullInfo?> queryMyFullInfo() async {
    try {
      final data = await HttpUtil.get(
        Urls.getProfile,
        options: domainJwtOptions,
      );
      if (data is Map) {
        final mapped = {
          'userID': data['user_id'],
          'nickname': data['nickname'],
          'faceURL': data['avatar'],
          'gender': data['gender'],
          'birth': data['birth'],
          'email': data['email'],
          'phoneNumber': data['phone'],
          'areaCode': data['area_code'],
          'ex': data['bio'],
        };
        return UserFullInfo.fromJson(mapped);
      }
      return null;
    } catch (e, s) {
      _catchErrorHelper(e, s);
      return null;
    }
  }

  static Future<UserFullInfo?> getUserProfileByOpenIMID(String openimUserID) async {
    try {
      final data = await HttpUtil.get(
        "${Urls.getProfileByOpenIMID}/$openimUserID",
        options: domainJwtOptions,
      );
      if (data is Map) {
        final mapped = {
          'userID': data['user_id'],
          'nickname': data['nickname'],
          'faceURL': data['avatar'],
          'gender': data['gender'],
          'birth': data['birth'],
          'email': data['email'],
          'phoneNumber': data['phone'],
          'areaCode': data['area_code'],
          'ex': data['bio'],
        };
        return UserFullInfo.fromJson(mapped);
      }
      return null;
    } catch (e, s) {
      _catchErrorHelper(e, s);
      return null;
    }
  }

  // static Future<bool> requestVerificationCode({
  //   String? areaCode,
  //   String? phoneNumber,
  //   String? email,
  //   required int usedFor,
  //   String? invitationCode,
  // }) async {
  //   return HttpUtil.post(
  //     Urls.getVerificationCode,
  //     data: {
  //       "areaCode": areaCode,
  //       "phoneNumber": phoneNumber,
  //       "email": email,
  //       'usedFor': usedFor,
  //       'invitationCode': invitationCode
  //     },
  //   ).then((value) {
  //     IMViews.showToast(StrRes.sentSuccessfully);
  //     return true;
  //   }).catchError((e, s) {
  //     _catchErrorHelper(e, s);

  //     return false;
  //   });
  // }
  static Future<bool> requestVerificationCode({
    required String phone,
    required String areaCode,
  }) async {
    debugPrint(Urls.getVerificationCode);
    return HttpUtil.post(
      Urls.getVerificationCode,
      data: {
        "phone": phone,
        "area_code": areaCode,
      },
    ).then((value) {
      debugPrint('验证码请求成功: $value');
      IMViews.showToast(StrRes.sentSuccessfully);
      return true;
    }).catchError((e, s) {
      debugPrint('验证码发送失败: $e, $s');
      _catchErrorHelper(e, s);
      return false;
    });
  }

  static Future<bool> sendEmailVerificationCode({
    required String email,
  }) async {
    return HttpUtil.post(
      Urls.sendEmailCode,
      data: {
        "email": email,
      },
    ).then((value) {
      debugPrint('邮箱验证码请求成功: $value');
      IMViews.showToast(StrRes.sentSuccessfully);
      return true;
    }).catchError((e, s) {
      debugPrint('邮箱验证码发送失败: $e, $s');
      _catchErrorHelper(e, s);
      return false;
    });
  }

  static Future<SignalingCertificate> getTokenForRTC(String roomID, String userID) async {
    return HttpUtil.post(
      Urls.getTokenForRTC,
      data: {
        "room": roomID,
        "identity": userID,
      },
      options: chatTokenOptions,
    ).then((value) {
      final signaling = SignalingCertificate.fromJson(value)..roomID = roomID;
      return signaling;
    }).catchError((e, s) {
      _catchErrorHelper(e, s);

      throw e;
    });
  }

  // static Future<dynamic> checkVerificationCode({
  //   String? areaCode,
  //   String? phoneNumber,
  //   String? email,
  //   required String verificationCode,
  //   required int usedFor,
  //   String? invitationCode,
  // }) {
  //   return HttpUtil.post(
  //     Urls.checkVerificationCode,
  //     data: {
  //       "phoneNumber": phoneNumber,
  //       "areaCode": areaCode,
  //       "email": email,
  //       "verifyCode": verificationCode,
  //       "usedFor": usedFor,
  //       'invitationCode': invitationCode
  //     },
  //   );
  // }

  static Future<dynamic> checkVerificationCode({
    String? areaCode,
    String? phoneNumber,
    String? email,
    required String verificationCode,
    required int usedFor,
    String? invitationCode,
  }) {
    return HttpUtil.post(
      Urls.checkVerificationCode,
      data: {
        "phone": phoneNumber ?? "",
        "verification_code": verificationCode,
        "area_code": areaCode ?? "",
      },
    ).then((value) {
        // 修复类型比较问题
      debugPrint(value.toString());
      return true;
    }).catchError((e, s) {
      debugPrint('验证码验证失败: $e, $s');
      throw e;
    });
  }

  
  static Future<dynamic> checkEmailVerificationCode({
    required String email,
    required String verificationCode,
  }) {
    return HttpUtil.post(
      Urls.checkEmailVerificationCode,
      data: {
        "email": email,
        "verification_code": verificationCode,
      },
    ).then((value) {
      debugPrint('邮箱验证码验证成功: $value');
      return true;
    }).catchError((e, s) {
      debugPrint('邮箱验证码验证失败: $e, $s');
      throw e;
    });
  }

  static Future<UpgradeInfoV2> checkUpgradeV2() {
    return dio.post<Map<String, dynamic>>(
      'https://www.pgyer.com/apiv2/app/check',
      options: Options(
        contentType: 'application/x-www-form-urlencoded',
      ),
      data: {
        '_api_key': '',
        'appKey': '',
      },
    ).then((resp) {
      Map<String, dynamic> map = resp.data!;
      if (map['code'] == 0) {
        return UpgradeInfoV2.fromJson(map['data']);
      }
      return Future.error(map);
    });
  }

  static Future<Map<String, dynamic>> getClientConfig() async {
    return {'discoverPageURL': Config.discoverPageURL, 'allowSendMsgNotFriend': Config.allowSendMsgNotFriend};
  }

  static void _catchErrorHelper(Object e, StackTrace s) {
    if (e is (int, String?)) {
      final errCode = e.$1;
      final errMsg = e.$2;
      _kickoff(errCode);

      Logger.print('e:$errCode s:$errMsg');
    } else {
      _catchError(e, s);
    }
  }

  static void _catchError(Object e, StackTrace s, {bool forceBack = true}) {
    IMViews.showToast(e.toString());

    if (forceBack) {
      final currentRoute = Get.currentRoute;
        // 添加智能判断逻辑
       // 如果已经在登录页面，不需要再次跳转
      if (currentRoute.contains('/login') || 
          currentRoute.contains('/register') || 
          currentRoute.contains('/splash')) {
          debugPrint("Paxiy Already on auth page, skipping logout: $currentRoute");
          Logger.print('Already on auth page, skipping logout: $currentRoute');
      }else{
        DataSp.removeLoginCertificate();
        Get.offAllNamed('/login');
      }
    }
  }

  // 发布帖子
  static Future<dynamic> createPost(CreatePostRequest request) async {
    final loginCert = DataSp.getLoginCertificate();
    if (loginCert == null || loginCert.token.isEmpty) {
      throw Exception('用户未登录或token无效');
    }
    return HttpUtil.post(
      Urls.createPost,
      data: request.toJson(),
      options: Options(
        headers: {
          // 尝试不同的认证头格式
          'Authorization': 'Bearer ${loginCert.token}',
          // 或者可能是：
          // 'token': loginCert.token,
          // 'X-Token': loginCert.token,
          'Content-Type': 'application/json',
        },
      ),
    );
  }

  /// 根据圈子获取帖子列表
  static Future<dynamic> getPostsByCircle({
    required String circleId,
    int page = 1,
    int pageSize = 20,
  }) {
    return HttpUtil.get(
      "${Urls.getPostsByCircle}/$circleId/posts", // 修改为正确的路径格式
      queryParameters: {
        'page': page,
        'page_size': pageSize,
      },
      options: Options(
        headers: {
          'Authorization': 'Bearer ${DataSp.getLoginCertificate()?.token ?? ''}',
          'Content-Type': 'application/json',
        },
      ),
    );
  }

  /// 根据标签获取帖子列表
  static Future<dynamic> getPostsByTag({
    required String tagId,
    int page = 1,
    int pageSize = 20,
  }) {
    return HttpUtil.get(
      Urls.getPostsByTag,
      queryParameters: {
        'tag_id': tagId,
        'page': page,
        'page_size': pageSize,
      },
    );
  }

    /// 获取所有标签
  static Future<dynamic> getTags() {
    return HttpUtil.get(
      Urls.getTags,
    );
  }

   /// 删除帖子
  static Future<dynamic> deletePost(String postId) async {
    final loginCert = DataSp.getLoginCertificate();
    if (loginCert == null || loginCert.token.isEmpty) {
      throw Exception('用户未登录或token无效');
    }
    
    return HttpUtil.delete(
      "${Config.domainBackendUrl}/api/v1/posts/$postId",
      options: Options(
        headers: {
          'Authorization': 'Bearer ${loginCert.token}',
          'Content-Type': 'application/json',
        },
      ),
    );
  }

  /// 更新帖子
  static Future<dynamic> updatePost({
    required String postId,
    String? content,
    List<int>? tagIds,
    String? title,
  }) async {
    final loginCert = DataSp.getLoginCertificate();
    if (loginCert == null || loginCert.token.isEmpty) {
      throw Exception('用户未登录或token无效');
    }

    Map<String, dynamic> data = {};
    if (content != null) data['content'] = content;
    if (tagIds != null) data['tag_ids'] = tagIds;
    if (title != null) data['title'] = title;
    
    return HttpUtil.put(
      "${Config.domainBackendUrl}/api/v1/posts/$postId",
      data: data,
      options: Options(
        headers: {
          'Authorization': 'Bearer ${loginCert.token}',
          'Content-Type': 'application/json',
        },
      ),
    );
  }

  static Future<dynamic> getAllCircles({
  String? type,
  String? country,
  String? city,
}) {
  return HttpUtil.get(
    "${Urls.getAllCircles}/", // 使用圈子列表端点
    queryParameters: {
      if (type != null) 'type': type,
      if (country != null) 'country': country,
      if (city != null) 'city': city,
    },
    options: Options(
      headers: {
        'Authorization': 'Bearer ${DataSp.getLoginCertificate()?.token ?? ''}',
        'Content-Type': 'application/json',
      },
    ),
  );
}

  /// 点赞帖子
  static Future<dynamic> likePost(String postId) async {
    final loginCert = DataSp.getLoginCertificate();
    if (loginCert == null || loginCert.token.isEmpty) {
      throw Exception('用户未登录或token无效');
    }

    return HttpUtil.post(
      "${Config.domainBackendUrl}/api/v1/posts/$postId/like",
      options: Options(
        headers: {
          'Authorization': 'Bearer ${loginCert.token}',
          'Content-Type': 'application/json',
        },
      ),
    );
  }

  /// 取消点赞帖子
  static Future<dynamic> unlikePost(String postId) async {
    final loginCert = DataSp.getLoginCertificate();
    if (loginCert == null || loginCert.token.isEmpty) {
      throw Exception('用户未登录或token无效');
    }

    return HttpUtil.delete(
      "${Config.domainBackendUrl}/api/v1/posts/$postId/like",
      options: Options(
        headers: {
          'Authorization': 'Bearer ${loginCert.token}',
          'Content-Type': 'application/json',
        },
      ),
    );
  }

  /// 收藏帖子
  static Future<dynamic> collectPost(String postId) async {
    final loginCert = DataSp.getLoginCertificate();
    if (loginCert == null || loginCert.token.isEmpty) {
      throw Exception('用户未登录或token无效');
    }

    return HttpUtil.post(
      "${Config.domainBackendUrl}/api/v1/posts/$postId/collect",
      options: Options(
        headers: {
          'Authorization': 'Bearer ${loginCert.token}',
          'Content-Type': 'application/json',
        },
      ),
    );
  }

  /// 取消收藏帖子
  static Future<dynamic> uncollectPost(String postId) async {
    final loginCert = DataSp.getLoginCertificate();
    if (loginCert == null || loginCert.token.isEmpty) {
      throw Exception('用户未登录或token无效');
    }

    return HttpUtil.delete(
      "${Config.domainBackendUrl}/api/v1/posts/$postId/collect",
      options: Options(
        headers: {
          'Authorization': 'Bearer ${loginCert.token}',
          'Content-Type': 'application/json',
        },
      ),
    );
  }

  /// 获取用户收藏的帖子列表
  static Future<dynamic> getUserCollectedPosts({
    required String userId,
    int page = 1,
    int pageSize = 20,
  }) async {
    final loginCert = DataSp.getLoginCertificate();
    if (loginCert == null || loginCert.token.isEmpty) {
      throw Exception('用户未登录或token无效');
    }

    return HttpUtil.get(
      "${Config.domainBackendUrl}/api/v1/users/$userId/collected-posts",
      queryParameters: {
        'page': page,
        'page_size': pageSize,
      },
      options: Options(
        headers: {
          'Authorization': 'Bearer ${loginCert.token}',
          'Content-Type': 'application/json',
        },
      ),
    );
  }

  /// 搜索帖子（支持关键词、分页、排序、可选圈子过滤）
  static Future<dynamic> searchPosts({
        required String keyword,
        int page = 1,
        int pageSize = 20,
        String? sortBy,
        String? sortOrder,
        String? circleId,
        }) {
    return HttpUtil.get(
        Urls.searchPosts,
        queryParameters: {
        'keyword': keyword,
        'page': page,
        'page_size': pageSize,
        if (sortBy != null) 'sort_by': sortBy,
        if (sortOrder != null) 'sort_order': sortOrder,
        if (circleId != null) 'circle_id': circleId,
        },
        options: Options(
          headers: {
          'Authorization': 'Bearer ${DataSp.getLoginCertificate()?.token ?? ''}',
          'Content-Type': 'application/json',
          },)
        );
  }

  static Future<dynamic> submitAnonymousFeedback({
    required String title,
    required String content,
    String? category,
    String? priority,
    String? contactEmail,
    String? contactPhone,
    List<String>? attachments,
  }) async {
    final payload = {
      'title': title,
      'content': content,
      if (category != null) 'category': category,
      if (priority != null) 'priority': priority,
      if (contactEmail != null) 'contact_email': contactEmail,
      if (contactPhone != null) 'contact_phone': contactPhone,
      if (attachments != null) 'attachments': attachments,
    };
    return HttpUtil.post(
      Urls.submitAnonymousFeedback,
      data: payload,
    );
  }
  /// 分享帖子：递增计数并返回固定路径
  static Future<dynamic> sharePost(String postId) async {
    final loginCert = DataSp.getLoginCertificate();
    if (loginCert == null || loginCert.token.isEmpty) {
      throw Exception('用户未登录或token无效');
    }

    return HttpUtil.post(
      "${Config.domainBackendUrl}/api/v1/posts/$postId/share",
      options: Options(
        headers: {
          'Authorization': 'Bearer ${loginCert.token}',
          'Content-Type': 'application/json',
        },
      ),
    );
  }
  static Future<dynamic> getPost(String postId) async {
    final loginCert = DataSp.getLoginCertificate();
    return HttpUtil.get(
      "${Config.domainBackendUrl}/api/v1/posts/$postId",
      options: Options(
        headers: {
          'Authorization': 'Bearer ${loginCert?.token ?? ''}',
          'Content-Type': 'application/json',
        },
      ),
    );
  }
}

